package taskinstance;

import java.util.ArrayList;

import datatransferinstance.DataTransferInstance;
import datatransferinstance.DataTransferInterface;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import taskmanager.TaskManager;

public class Task implements Runnable{
  
  public static Logger logger = Logger.getLogger("");
  
  protected DataTransferInterface dtf;
  private String sourceIp;
  protected String targetIp;
  protected String fileName;
  
  boolean isPending = true;
  
  protected ArrayList<Task> completeArrayList;
  protected ArrayList<Task> failedArrayList;
  protected ArrayList<Task> runningArrayList;
  
  protected TaskManager tm;
  
  public Task() {};
  public Task(String sourceIp, String targetIp, String fileName) {
    PropertyConfigurator.configure("log4j.properties");
    this.dtf = new DataTransferInstance(fileName, targetIp);
    this.sourceIp = sourceIp;
    this.targetIp = targetIp;
    this.fileName = fileName;
  }
  
  public void setObserver(TaskManager tm) {
    this.tm = tm;
    this.completeArrayList = tm.getCompleteList();
    this.failedArrayList = tm.getFailedList();
    this.runningArrayList = tm.getRunningList();
  }
  
  public void setTaskContainer(TaskManager tm) {
    this.tm = tm;
  }
  
  public void run() {
    tm.lockTargetIp(targetIp);
    isPending = false;
    logger.info("Start: [" + this + "]");
    dtf.start();
    while (!dtf.isComplete()) {
      try {
        Thread.sleep(1000);  
        if (dtf.isError()) {
          tm.releaseTargetIp(targetIp);
          synchronized (runningArrayList) {
            runningArrayList.remove(this);
            failedArrayList.add(this);
            return;
          }
        }
      } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
    tm.releaseTargetIp(targetIp);
    synchronized (runningArrayList) {
      runningArrayList.remove(this);
      completeArrayList.add(this);
    }
    logger.info("Finish: [" + this + "]");
  }
  
  public Boolean isPending() {
    return isPending;
  }
  
  public String getTargetIp() {
    return targetIp;
  }
  
  public String getFileName() {
    return fileName;
  }
  
  public String getProgress() {
    return dtf.getState();
  }
  
  public void suspend() {
    dtf.suspend();
    // TODO release clock.
    // tm.releaseTargetIp(targetIp);
  }
  
  public void resume() {
    dtf.resume();
    // TODO acquire clock.
    // tm.lockTargetIp(targetIp);
  }
}
